package com.emm.yixun.openapi.aop;

import com.alibaba.fastjson.JSON;
import com.emm.yixun.common.model.ResourcesConfig;
import com.emm.yixun.common.model.dto.ResourcesConfigDto;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.openapi.anotations.MerchantApiConfig;
import com.emm.yixun.system.service.app.MerchantResourcesAppFacade;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by Administrator on 2017/8/10.
 */
@Aspect
@Component
public class MerchantApiAdivsor {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MerchantResourcesAppFacade resourcesConfigAppFacade;

    @Pointcut("@annotation(com.emm.yixun.openapi.anotations.MerchantApiConfig)")
    public void functionAspect(){}

    @Around(value = "functionAspect()")
    public void doAround(ProceedingJoinPoint joinPoint){
        //获取注解参数
        //查询获取所要执行的方法
        //判断是否继续执行方法
        try {
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            MerchantApiConfig merchantApiConfig = method.getAnnotation(MerchantApiConfig.class);
            if (null == merchantApiConfig) {
//                joinPoint.proceed();
                logger.error("注解获取失败");
            }

            Object[] args = joinPoint.getArgs();
            Long merchantId = null;
            for(Object o : args){
                if(o instanceof String){
                    //获取body,解析body,最终获取merchantId，查询数据库配置信息
                    Map<String,Object> mapParent  = JSON.parseObject(o.toString(),Map.class);
                    if(mapParent.containsKey("params")){
                        Map<String,Object> map =JSON.parseObject(JSON.parseObject(o.toString(),Map.class).get("params").toString()) ;
                        if(map.containsKey("merchantId")){
                            merchantId = Long.parseLong(map.get("merchantId").toString());
                        }
                    }
                }
            }

            if(null == merchantId){
                //先抛出异常
                logger.error("商户定制需求请求失败,商户id获取失败");
                throw  new Throwable();
            }

            String resourcesUrl = merchantApiConfig.resourcesUrl();
            // todo  加入缓存
            ResourcesConfig resourcesConfig=null;
            ResourcesConfigDto resourcesConfigDto=new ResourcesConfigDto();
            resourcesConfigDto.setUrl(resourcesUrl);
            resourcesConfigDto.setMerchantId(merchantId);
            ResponseList<ResourcesConfig> responseList= resourcesConfigAppFacade.findByDto(resourcesConfigDto);
            if(!responseList.isSuccess() || null==responseList.getEntity() || responseList.getEntity().size()==0){
                joinPoint.proceed();
            }
            resourcesConfig=responseList.getEntity().get(0);

           //反射执行相应方法
            WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
            Class  clazz =  wac.getBean(resourcesConfig.getResourcesCode()).getClass();
            Method doBusiness = clazz.getDeclaredMethod(resourcesConfig.getUrl(), Model.class, HttpServletRequest.class, HttpServletResponse.class,String.class);
            // todo 参数初始化,反射时调用的object，依然会有类型转换，此时的参数初始化只为保证类型正确
            Model m = null;
            HttpServletRequest req = null;
            HttpServletResponse res = null;
            String body = null;
            for(Object param : args){
                if(param instanceof Model){
                    m =(Model)param;
                    continue;
                }
                if(param instanceof HttpServletRequest){
                    req = (HttpServletRequest)param;
                    continue;
                }
                if(param instanceof HttpServletResponse){
                    res = (HttpServletResponse)param;
                    continue;
                }
                if(param instanceof String){
                    body = (String)param;
                    continue;
                }
            }
            doBusiness.invoke( wac.getBean(resourcesConfig.getResourcesCode()),m,req,res,body);

        }catch (Throwable e){
            logger.error("商户定制需求请求失败："+e);
        }
    }

}
